Haskell, GTK4 and pictures on the fly

As part of my further experiments with GTK4 and Haskell, I wanted to vary gtk-picture by creating the Picture programatically. I named the alternative gtk-dynamic-picture.

Diagrams

I created the picture using the Diagrams project. I looked at various backends:

  • the diagrams-gtk package, based on Cairo, renders to values of the gtk package, not the gi-gtk package;
  • the diagrams-cairo package can render to a buffer in memory with the pixel format CAIRO_FORMAT_ARGB32. That format has alpha in the upper byte, then red, then green, then blue. The pixels are, however, stored native-endian; that is, on little endian tx86_64, the order of the bytes is B G R A. Also, pre-multiplied alpha is used. (For example, 50% transparent red is 0x80800000, not 0x80ff0000.); and
  • the diagrams-rasterific package, based on the Rasterific package, renders to values of type Image PixelRGBA8 (provided by the JuicyPixels package). Pixels are stored in the order R G B A.

Ultimately, given the pixel format of a Pixbuf value (R G B A), I used diagrams-rasterific as the backend.

The first step was to yield an Image PixelRGBA8 from a Diagram B:

Picture

The gi-gtk package provides:

and the gi-gdk package provides Texture, which satisfies the IsPaintable constraint, and:

So, the final step was to yield a Picture value from a Texture value and, in turn, a Texture value from a Pixbuf:

imagePixelRGBA8ToPixbuf

The missing link was:

imageData image has type Data.Vector.Storable.Vector Word8. A buffer is allocated (mallocBytes n) and the bytes copied into it (copyBytes pixbufPtr ptr n). free is specified as the destroy function.